﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GameEngine;
using Daphne.GameShared;

namespace Daphne.GameEngineModule
{
    /// <summary>
    /// Game Engine Adapter Class for Daphne Metro Edition
    /// TO-DO: Change in checkes type means only changing GameManager, not Adapter class
    /// TO-DO: do commenting
    /// </summary>
    internal class GameManagerAdapter: IUserMoveEntering, IGameBoardForEditor, IGameBoard
    {
        private GameManager _gameManager;
        private Move _moveInProgress;

        /// <summary>
        /// Constructor
        /// </summary>
        public GameManagerAdapter()
        { 
            // TO-DO: think of creating variable game manager
            _gameManager = GameManagerFactory.CreateGameManager(enumGameType.Czech);
            _gameManager.NewGame();
        }

        #region Interface IUserMoveEntering
        
        public bool CanFigureMove(Position source)
        {
            List<Position> dummy;
            return _gameManager.CanThisFigureMove(source, out dummy);
        }

        public List<Position> GetFigureTargetFields(Position source)
        {
            List<Position> targets = new List<Position>();
            _gameManager.GetFigureMoves(source, targets);
            return targets;
        }

        public List<Position> GetFiguresToMove()
        {
            return _gameManager.GetFiguresToMove();
        }

        public void DoMoveStep(Position source, Position target)
        {
            Move moveStep = _gameManager.CompleteMoveStep(source, target);
            _gameManager.DoMoveStep(moveStep);

            if (_moveInProgress == null)
                _moveInProgress = moveStep;
            else
            {
                Move lastMove = _moveInProgress;
                while (lastMove.nextMove != null)
                    lastMove = lastMove.nextMove;
                lastMove.nextMove = moveStep;
            }
        }

        public Position? IsLastMoveStepCapturing()
        {
            // check, if we have move
            if (_moveInProgress == null)
                return null;

            // find the last move step
            Move lastMove = _moveInProgress;
            while (lastMove.nextMove != null)
                lastMove = lastMove.nextMove;

            // check, if it is capturing move and return captured piece position
            if (lastMove.RemovingFigure)
                return lastMove.removedFigurePlace;
            else
                return null;
        }

        public bool DoesMoveContinue()
        {
            Move lastMove = _moveInProgress;
            while (lastMove.nextMove != null)
                lastMove = lastMove.nextMove;
            return _gameManager.DoesMoveContinue(lastMove, lastMove.endPos);
        }

        public void FinalizeMove()
        {
            _gameManager.FinalizeMove(_moveInProgress);
            _moveInProgress = null;
        }

        #endregion

        #region Interface IGameBoard
        
        public void PlaceFigure(Position pos, enumFigureType figureType)
        {
            _gameManager.GameBoard.PlaceFigure(pos, figureType);
        }

        public void ClearField(Position pos)
        {
            _gameManager.GameBoard.RemoveFigure(pos);
        }

        public void ClearBoard()
        {
            _gameManager.GameBoard.CleanBoard();
        }

        public void SetStartupPosition()
        {
            _gameManager.GameBoard.SetupStartPosition(_gameManager.PieceRows);
        }

        public void SetSTM(enumFigureColor stm)
        {
            _gameManager.GameBoard.SetOnMove(stm);
        }

        public enumFigureColor GetSTM()
        {
            return _gameManager.GameBoard.OnMove;
        }

        public BitBoard PackPosition()
        {
            return _gameManager.GameBoard.PackGameBoard();
        }

        public void UnpackPosition(BitBoard bb)
        {
            _gameManager.GameBoard.UnpackGameBoard(bb);
        }

        #endregion

        public int Size
        {
            get { return _gameManager.GameBoard.Size; }
        }

        public enumFigureType GetField(Position pos)
        {
            return _gameManager.GameBoard.GetField(pos);
        }

        public enumFigureColor GetFieldColor(Position pos)
        {
            return _gameManager.GameBoard.GetFieldColor(pos.Row, pos.Col);
        }
    }
}
